<?php

namespace app\admin\controller\shopro\third;

use app\common\controller\Backend;
use app\admin\model\shopro\commission\Agent as AgentModel;
use app\admin\model\shopro\user\User as UserModel;
use app\admin\model\shopro\order\Order as OrderModel;
use app\admin\model\shopro\commission\Log as LogModel;
use addons\shopro\service\user\UserAuth;
use addons\shopro\service\third\wechat\Wechat as WechatService;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;

use Exception;
use think\Db;
use think\exception\DbException;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 医生管理
 *
 * @icon fa fa-circle-o
 */
class Doctors extends Backend
{

    /**
     * Doctor模型对象
     * @var \app\admin\model\Doctor
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\Doctor;

    }



    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */

    /**
     * 查看
     *
     * @return string|Json
     * @throws \think\Exception
     * @throws DbException
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if (false === $this->request->isAjax()) {
            return $this->view->fetch();
        }
        //如果发送的来源是 Selectpage，则转发到 Selectpage
        if ($this->request->request('keyField')) {
            return $this->selectpage();
        }
        // 增加统计成单量和成单金额,推广用户数
        $users = Db::name('user')->field('parent_user_id, count(parent_user_id) users_total')
          ->where('parent_user_id', '>', 0)->group('parent_user_id')->select();
        $userTotals = [];
        foreach ($users as $u) {
            $arr = collection($u)->toArray();
            $userTotals[$arr['parent_user_id']] = $arr['users_total'];
            $doctor = $this->model->where('user_id', $arr['parent_user_id'])->find();
            if ($doctor) {
                $doctor->users_total = $userTotals[$arr['parent_user_id']];
                $doctor->save();
            }
        }

        $statistic = Db::name('shopro_order')->field('parent_user_id, count(parent_user_id) order_total,sum(pay_fee-dispatch_amount) total_consume')
          ->where('status', 'paid')->group('parent_user_id')->select();
        $totals = [];
        foreach($statistic as $s) {
            $arr = collection($s)->toArray();
            $doctor = $this->model->where('user_id', $arr['parent_user_id'])->find();
            if ($doctor) {
                $doctor->order_total = $arr['order_total'];
                $doctor->total_consume = $arr['total_consume'];
                $doctor->save();
            }
        }
        

        [$where, $sort, $order, $offset, $limit] = $this->buildparams();
        $list = $this->model
            ->where($where)
            ->order($sort, $order)
            ->paginate($limit);
        $result = ['total' => $list->total(), 'rows' => $list->items()];
        return json($result);
    }

    public function exportDoctor()
    {
        // 超时、超内存设置
        ini_set('memory_limit', '1024M');
        ini_set('max_execution_time', '0');

        // 初始化表
        $spreadsheet = new Spreadsheet();
        $worksheet = $spreadsheet->setActiveSheetIndex(0);
        $worksheet->getDefaultRowDimension()->setRowHeight(25);  // 设置默认行高
        $worksheet->getDefaultColumnDimension()->setAutoSize(true);  // 设置自动宽

        // 设置标题
        foreach (['医生姓名', '所属医院', '推广用户数', '成单数量', '成单总金额'] as $key => $value) {
            $worksheet->setCellValueByColumnAndRow($key + 1, 1, __($value));
            $worksheet->getCellByColumnAndRow($key + 1, 1)->getStyle()->applyFromArray([
                'font'      => [
                    'name'  => 'Arial',
                    'color' => ['rgb' => '000000'],
                    'size'  => 12,
                    'bold'  => true
                ],
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical'   => Alignment::VERTICAL_CENTER,
                ]
            ]);
        }
        /*
        $worksheet->getColumnDimensionByColumn(2)->setWidth(20);  // 设置宽度
        $worksheet->getColumnDimensionByColumn(3)->setWidth(20);  // 设置宽度
        $worksheet->getColumnDimensionByColumn(4)->setWidth(20);  // 设置宽度
        $worksheet->getColumnDimensionByColumn(7)->setWidth(20);  // 设置宽度
        $worksheet->getColumnDimensionByColumn(8)->setWidth(20);  // 设置宽度
        */

        // 获取条件
        /*
        $whereIds = $ids === 'all' ? '1=1' : ['id' => ['in', explode(',', $ids)]];
        $this->request->get(['search' => $search, 'ids' => $ids, 'filter' => $filter, 'op' => $op]);
        list($where, $sort, $order, $offset, $limit) = $this->buildparams();
        */

        // 查询数据
        $row = 1;
        $this->model
            ->chunk(1000, function ($items) use (&$row, &$worksheet) {
                foreach ($items as $item) {
                    $row++;
                    $col = 1;
                    $values = [
                        'doctor_name' => $item['doctor_name'],
                        'hospital' => $item['hospital'],
                        'users_total' => $item['users_total'],
                        'order_total' => $item['order_total'],
                        'total_consume' => $item['total_consume'],
                    ];

                    // 其他
                    foreach ($values as $value) {
                        $worksheet->setCellValueByColumnAndRow($col, $row, $value);
                        $worksheet->getStyleByColumnAndRow($col, $row)->getNumberFormat()
                            ->setFormatCode(NumberFormat::FORMAT_TEXT);
                        $worksheet->getCellByColumnAndRow($col, $row)->getStyle()->applyFromArray([
                            'alignment' => [
                                'horizontal' => Alignment::HORIZONTAL_CENTER,
                                'vertical'   => Alignment::VERTICAL_CENTER,
                            ]
                        ]);
                        $col++;
                    }
                }
            });

        // 导出文件
        // Redirect output to a client’s web browser (Excel2007)
        $fileName = date('YmdHis');
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="' . $fileName . '.xlsx"');
        header('Cache-Control: max-age=0');
        // If you're serving to IE 9, then the following may be needed
        header('Cache-Control: max-age=1');
        // If you're serving to IE over SSL, then the following may be needed
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');  // always modified
        header('Cache-Control: cache, must-revalidate');  // HTTP/1.1
        header('Pragma: public');  // HTTP/1.0
        $objWriter = IOFactory::createWriter($spreadsheet, 'Xlsx');
        $objWriter->save('php://output');
        exit;
         
    }

    /**
     * 添加
     *
     * @return string
     * @throws \think\Exception
     */
    public function add()
    {
        if (false === $this->request->isPost()) {
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);

        if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
            $params[$this->dataLimitField] = $this->auth->id;
        }
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                $this->model->validateFailException()->validate($validate);
            }
            // 添加到用户表
            $userParams = ['email' => time() . "@hsintiao.com"];
            $userAuth = new UserAuth();
            $auth = $userAuth->register($userParams);
            $user = $auth->getUser();
            $params['user_id'] = $user->id;

            $result = $this->model->allowField(true)->save($params);
            // 添加到分销商标
            $agentStatus = AgentModel::AGENT_STATUS_NORMAL;
            // 可以直接添加分销商信息
            AgentModel::create([
                'user_id' => $user->id,
                'level' => 1,  // 默认分销商等级
                'status' => $agentStatus,
                'apply_info' => [],
                'apply_num' => 1,
                'become_time' => time()
            ]);
            // 添加分销商状态记录
            LogModel::add($user->id, 'agent', ['type' => 'status', 'value' => $agentStatus]);

            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($result === false) {
            $this->error(__('No rows were inserted'));
        }
        $this->success();
    }

    /**
     * 编辑
     *
     * @param $ids
     * @return string
     * @throws DbException
     * @throws \think\Exception
     */
    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }
            $result = $row->allowField(true)->save($params);
            Db::commit();
        } catch (ValidateException|PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }

    /**
     * 删除
     *
     * @param $ids
     * @return void
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function del($ids = null)
    {
        if (false === $this->request->isPost()) {
            $this->error(__("Invalid parameters"));
        }
        $ids = $ids ?: $this->request->post("ids");
        if (empty($ids)) {
            $this->error(__('Parameter %s can not be empty', 'ids'));
        }
        $pk = $this->model->getPk();
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            $this->model->where($this->dataLimitField, 'in', $adminIds);
        }
        $list = $this->model->where($pk, 'in', $ids)->select();

        $count = 0;
        Db::startTrans();
        try {
            foreach ($list as $item) {
                $count += $item->delete();
            }
            Db::commit();
        } catch (PDOException|Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        }
        $this->error(__('No rows were deleted'));
    }

    public function orders()
    {
        // 查找
        $userId = $this->request->get("user_id");
        $orders = OrderModel::where('parent_user_id', $userId)->where('status', 'paid')->with(['items', 'patient', 'user'])->select();
        $data = [];
        foreach ($orders as $o) {
            $arr = [];
            // echo $o->order_sn . "<br />";
            $arr['order_sn'] = $o->order_sn; 
            // echo $o->user->nickname . "<br />";
            $arr['nickname'] = $o->user->nickname; 
            $patientName = "-";
            if ($o->patient) {
                // echo $o->patient->real_name;
                $patientName = $o->patient->real_name;
            }
            $arr['patient'] = $patientName; 
            // echo "<br />";
            // echo $o->order_amount . "<br />";
            $arr['order_amount'] = $o->order_amount;
            $itemStr = "";
            foreach ($o->items as $item) {
                // echo $item->goods_title . ",";
                // echo $item->goods_sku_text . ",";
                $itemStr .= $item->goods_title . ",";
            }
            $arr['item'] = $itemStr;
            // echo "<br />";
            // echo $o->paid_time . "<br />";
            $arr['paid_time'] = $o->paid_time;
            $data[] = $arr;
        }
        $this->view->assign('data', $data);
        return $this->view->fetch();
    }

    public function exportOrder()
    {
        // 超时、超内存设置
        ini_set('memory_limit', '1024M');
        ini_set('max_execution_time', '0');

        // 初始化表
        $spreadsheet = new Spreadsheet();
        $worksheet = $spreadsheet->setActiveSheetIndex(0);
        $worksheet->getDefaultRowDimension()->setRowHeight(25);  // 设置默认行高
        $worksheet->getDefaultColumnDimension()->setAutoSize(true);  // 设置自动宽

        // 设置标题
        foreach (['订单号', '成单商品', '成单金额', '用户昵称', '就诊人姓名', '成单时间'] as $key => $value) {
            $worksheet->setCellValueByColumnAndRow($key + 1, 1, __($value));
            $worksheet->getCellByColumnAndRow($key + 1, 1)->getStyle()->applyFromArray([
                'font'      => [
                    'name'  => 'Arial',
                    'color' => ['rgb' => '000000'],
                    'size'  => 12,
                    'bold'  => true
                ],
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical'   => Alignment::VERTICAL_CENTER,
                ]
            ]);
        }
        /*
        $worksheet->getColumnDimensionByColumn(2)->setWidth(20);  // 设置宽度
        $worksheet->getColumnDimensionByColumn(3)->setWidth(20);  // 设置宽度
        $worksheet->getColumnDimensionByColumn(4)->setWidth(20);  // 设置宽度
        $worksheet->getColumnDimensionByColumn(7)->setWidth(20);  // 设置宽度
        $worksheet->getColumnDimensionByColumn(8)->setWidth(20);  // 设置宽度
        */

        // 获取条件
        /*
        $whereIds = $ids === 'all' ? '1=1' : ['id' => ['in', explode(',', $ids)]];
        $this->request->get(['search' => $search, 'ids' => $ids, 'filter' => $filter, 'op' => $op]);
        list($where, $sort, $order, $offset, $limit) = $this->buildparams();
        */

        // 查询数据
        $row = 1;
        $userId = $this->request->get('user_id');
        OrderModel::where('parent_user_id', $userId)->where('status', 'paid')
          ->with(['items', 'patient', 'user'])->chunk(1000, function ($items) use (&$row, &$worksheet) {
                foreach ($items as $item) {
                    $row++;
                    $col = 1;
                    $values = [];
                    $values['order_sn'] = $item->order_sn; 
                    $itemStr = "";
                    foreach ($item->items as $im) {
                        $itemStr .= $im->goods_title . ",";
                    }
                    $values['item'] = $itemStr;
                    $values['order_amount'] = $item->order_amount;
                    $values['nickname'] = $item->user->nickname; 
                    $patientName = "-";
                    if ($item->patient) {
                        $patientName = $item->patient->real_name;
                    }
                    $values['patient'] = $patientName; 
                    $values['paid_time'] = $item->paid_time;

                    // 其他
                    foreach ($values as $value) {
                        $worksheet->setCellValueByColumnAndRow($col, $row, $value);
                        $worksheet->getStyleByColumnAndRow($col, $row)->getNumberFormat()
                            ->setFormatCode(NumberFormat::FORMAT_TEXT);
                        $worksheet->getCellByColumnAndRow($col, $row)->getStyle()->applyFromArray([
                            'alignment' => [
                                'horizontal' => Alignment::HORIZONTAL_CENTER,
                                'vertical'   => Alignment::VERTICAL_CENTER,
                            ]
                        ]);
                        $col++;
                    }
                }
            });

        // 导出文件
        // Redirect output to a client’s web browser (Excel2007)
        $fileName = date('YmdHis');
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="' . $fileName . '.xlsx"');
        header('Cache-Control: max-age=0');
        // If you're serving to IE 9, then the following may be needed
        header('Cache-Control: max-age=1');
        // If you're serving to IE over SSL, then the following may be needed
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');  // always modified
        header('Cache-Control: cache, must-revalidate');  // HTTP/1.1
        header('Pragma: public');  // HTTP/1.0
        $objWriter = IOFactory::createWriter($spreadsheet, 'Xlsx');
        $objWriter->save('php://output');
        exit;
         
    }

    public function wxcode()
    {
        $userId = $this->request->get("user_id");
        $this->platform = 'miniProgram';

        $this->payload = ["path" => "/pages/index/index?spm=".$userId.".1.0.3.1"];


        $this->wechat = new WechatService($this->platform, $this->payload);
    
        $mp = $this->wechat->getApp();
        $path = $this->payload['path'];
        list($page, $scene) = explode('?', $path);

        $content = $mp->app_code->getUnlimit($scene, [
            'page' => substr($page, 1),
            'is_hyaline' => true,
            // 'env_version' => 'develop'
            'env_version' => 'release'
        ]);

        if ($content instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
            $str = $content->getBodyContents();
            $img = $this->saveWxCode($str, $userId);
            // $img = response($content->getBody(), 200, ['Content-Length' => strlen($content->getBodyContents())])->contentType('image/png');
        } else {
            $img = "";
        }
        // echo "<img src=".cdnurl($img, true)." width=270 />";
        $this->assign('img', cdnurl($img, true));
        return $this->view->fetch();
    }

    private function saveWxCode($str, $userId)
    {
        $codeDir = "/uploads/wxcode";
        $this->curPath = ROOT_PATH . "public"; 
        $destDir = $this->curPath . $codeDir;
        $this->createDir($destDir);

        $iconPath = $destDir . '/' . $userId . '.png';
        $res = file_put_contents($iconPath,$str);

        return $codeDir . "/" . $userId . '.png';
    }
    
    private function createDir($destDir)
    {
        if (!is_dir($destDir)) {
            @mkdir($destDir, 0755, true);
        }
    }

}
